package tree;
import java.util.*;
import ttt.*;

public class Tree {
	
	private Node root;
	private Node currentNode;
	private BoardEvaluator eval = new BoardEvaluator();
	private int mark;
	
	public Tree(int mark) {
		this.mark = mark;
	}
	
	public boolean equalsByRotation(int[] constArray, int[] rotArray) {
		return eval.equalsByRotation(constArray, rotArray);
	}
	
	public int status(int[] board) {
		return eval.status(board);
	}

	private int findNextMoveAndAdvance(Node itNode) {
		Node tieNode = null;
		for(Node node : itNode) {
			if(node.winner() == mark) {
				currentNode = node;
				return node.getIndex();
			}
			else if(node.winner() == BoardEvaluator.STATUS_TIE)
				tieNode = node;
		}
		
		if(tieNode != null) {
			currentNode = tieNode;
			return tieNode.getIndex();
		}
		else
			return BoardEvaluator.STATUS_UNDEFIND;
	}
	
	public int getNextMove(int index) {
		if(root == null && mark == TicTacToe.X_MARK) {
			Random random = new Random();
			int i = random.nextInt(9);
			int[] board = new int[9];
			board[i] = TicTacToe.X_MARK;
			root = buildTree(board, TicTacToe.O_MARK, 0);
			currentNode = root;
			return i;
		}
		else if(root == null && mark == TicTacToe.O_MARK) {
			int[] board = new int[9];
			board[index] = TicTacToe.X_MARK;
			root = buildTree(board, TicTacToe.O_MARK, 0);
			currentNode = root;
			return findNextMoveAndAdvance(root);
		}
		else {
			for(Node node : currentNode) {
				if(index == node.getIndex())
					currentNode = node;
			}
			
			return findNextMoveAndAdvance(currentNode);
		}
	}
	
	public void reset(int newMark) {
		currentNode = root;
		mark = newMark;
	}
	
	public Node getRoot() {
		if(root != null)
			return root;
		
		Node node = buildTree(new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0}, 1, 0);
		currentNode = node;
		root = node;
		return node;
	}
	
	public Node buildTree(int[] board, int turn, int j) {		
		int win;
		if((win = status(board)) != BoardEvaluator.STATUS_UNDEFIND)
			return new TreeLeaf(win, j);
		
		ArrayList<Node> children = new ArrayList<Node>();
		for(int i = 0; i < 9; i++) {
			if(board[i] == TicTacToe.EMPTY_MARK) {
				int[] nextBoard = board.clone();
				nextBoard[i] = turn;
				children.add(buildTree(nextBoard, -turn, i));
			}
		}
		
		Node node = new TreeNode(children, -turn, j);
		return node;
	}
}
